package com.hbl.cgs.cgsagent.plugin;

import com.fasterxml.jackson.databind.JsonNode;
import com.hbl.cgs.cgsagent.Constants;

import java.lang.reflect.InvocationTargetException;

public class DefaultPluginFactory implements PluginFactory {
    @Override
    public Plugin create(JsonNode context) throws PluginConfigException {
        if (!context.has(Constants.KEY_PLUGIN)) {
            throw new PluginConfigException("unable to create plugin");
        }
        String plugin = context.get(Constants.KEY_PLUGIN).asText();
        Class<? extends PluginFactory> factoryClass = getFactoryClass(plugin);
        try {
            PluginFactory factory = factoryClass.getDeclaredConstructor().newInstance();
            return factory.create(context);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            throw new PluginConfigException("unable to load plugin");
        } catch (InvocationTargetException e) {
            e.printStackTrace();
            throw new PluginConfigException("unable to load plugin");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            throw new PluginConfigException("unable to load plugin");
        } catch (InstantiationException e) {
            e.printStackTrace();
            throw new PluginConfigException("unable to load plugin");
        }
    }

    private Class<? extends PluginFactory> getFactoryClass(String plugin) {
        PluginType pluginType = PluginType.OTHER;
        try {
            pluginType = PluginType.valueOf(plugin.toUpperCase());
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }
        String pluginFactoryClassName = pluginType.equals(PluginType.OTHER) ? plugin : pluginType.getFactoryName();
        try {
            return (Class<? extends PluginFactory>) Class.forName(pluginFactoryClassName);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            throw new PluginConfigException("unable to load plugin type");
        }
    }
}
